home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: New Zealand Amiga Users Group / New Zealand Amiga Users Group Newsdisk v27 (1989-12)(NZAmigaUG).zip / New Zealand Amiga Users Group Newsdisk v27 (1989-12)(NZAmigaUG).adf / Cal / cal.asm < prev    next >
Assembly Source File  |  1993-12-03  |  39KB  |  1,335 lines

  1.  
  2.  
  3. ;    Version 1.0
  4.  
  5. ;    Cal.asm
  6. ;
  7. ;    by Steve Martin
  8. ;
  9. ;    Hope you understand this mess.
  10. ;
  11. ;  Copyright:    People can do what they want with this progrm except
  12. ;        to sell it, also I am not responsible for anything.
  13.     nolist
  14.     incdir  'vd0:include/'
  15.     include    'exec/exec_lib.i'
  16.     ;include 'exec/types.i'
  17.     ;include 'exec/memory.i'
  18.     ;include 'intuition/intuition.i'
  19.     include    "libraries/dos_lib.i"
  20.  
  21.     xref    _LVOOpenLibrary
  22.     xref    _LVOCloseLibrary
  23.     xref    _LVOInput
  24.     xref    _LVOOutput
  25.     xref    _LVORead
  26.     xref    _LVOWrite
  27.  
  28.     
  29. ;    list
  30.  
  31. ExecBase equ    4
  32.  
  33. calexec MACRO
  34.     move.l    ExecBase,a6
  35.     jsr    _LVO\1(a6)
  36.     ENDM
  37.  
  38. caldos    MACRO
  39.     move.l    DosBase,a6
  40.     jsr    _LVO\1(a6)
  41.     ENDM
  42.  
  43.  
  44. ;    A0 holds the address of the command parameters
  45. ;    D0 holds the length of the command parameters    
  46. ;    command string ends with $0A
  47.  
  48.  
  49.  
  50. start    move.l    a0,ipadd    store address of command line
  51.     move.w    d0,iplen    store length of command line
  52.  
  53. getDOS    lea.l    DosName,a1    library to open
  54.     moveq    #0,d0        library version (do not care)
  55.     calexec    OpenLibrary    open library
  56.     tst.l    d0        test if succesful (0 = NG)
  57.     bne.s    DosOK
  58.     moveq    #20,d0        return code to tell user system problem
  59.     rts            return to operating system
  60.  
  61. DosOK    move.l    d0,DosBase    Save DOS base pointer
  62.     caldos    Input        find standard input
  63.     move.l    D0,stdin    save
  64.     caldos    Output        find standard output
  65.     move.l    D0,stdout    save
  66.  
  67. ;*************************************************************************
  68.  
  69. iptype    bsr    getchar        get first character form input
  70.  
  71.     cmpi.b    #"$",d1        is the number enter in HEX
  72.     bne.s    ipt2
  73.     moveq    #0,d1
  74.     bra    Selip
  75. ipt2    cmpi.b    #"@",d1        is the number enter in OCT
  76.     bne.s    ipt3
  77.     moveq    #1,d1
  78.     bra    Selip
  79. ipt3    cmpi.b    #"%",d1        is the number enter in binary
  80.     bne    ipt4
  81.     moveq    #2,d1
  82.     bra    Selip
  83. ipt4    cmpi.b    #"-",d1        is the number negative    
  84.     bne    others    
  85.     seq    neg        set neg flag
  86.     moveq    #3,d1
  87.     bra    Selip
  88.  
  89. others    subi.b    #$30,d1        is input < 0
  90.     bmi    error1        yes, error
  91.     cmpi.b    #9,d1        is the character a decimal number
  92.     bgt    error1
  93.     
  94.     sub.l    #1,ipadd    move pointer back a character
  95.     add.w    #1,iplen    incrememt length not read
  96.  
  97.     moveq    #3,d1        d1 = decimal input
  98.     
  99.  
  100. Selip    lsl    #2,d1        cal index for jump table
  101.     lea    Selipt,a0    get address of jump table
  102.     move.l    0(a0,d1.w),a0    get address of input routine
  103.     jsr    (a0)
  104.     bcs    error1
  105.     bsr    opert        if operator, action it
  106.     bmi    result
  107.     bcc.s    nip        get net input type        
  108.     bra    operr        if operator err
  109. nip    bra    iptype        check input type
  110.  
  111. Selipt    dc.l    HEXip,OCTip,BINip,DECip
  112.  
  113. ;*************************************************************************
  114.  
  115. result    clr    d0
  116.     move.b    func,d0        get function pointer
  117.     subq    #1,d0
  118.     lsl    #2,d0        cal index for jump table
  119.     lea    selfunc,a0    get address of jump table
  120.     move.l    0(a0,d0.w),a0    get address of func routine
  121.     jsr    (a0)
  122.     tst.b    err
  123.     bne    error1
  124.     bsr    HtoA
  125.     bsr    OtoA    
  126.     bsr    BtoA    
  127.     bsr    DtoA
  128.     lea    BuffHS,a3
  129.     bsr    nextlin
  130.     lea    BuffOS,a3
  131.     bsr    nextlin
  132.     lea    BuffBS,a3
  133.     bsr    nextlin
  134.     lea    BuffDS,a3
  135.     bsr    nextlin
  136.     lea    blank,a3
  137.     bsr    nextlin
  138.     bra    quit
  139.  
  140. selfunc    dc.l    add,sub,mult,div
  141.  
  142. ;*************************************************************************
  143.  
  144. quit    move.l    DosBase,a1    Close DOS library
  145.     calexec    CloseLibrary
  146.     moveq    #0,d0        Zero return code
  147.     rts            return to Operating System
  148.  
  149. ;*************************************************************************
  150.  
  151. opert    move.b    func,d2
  152.     bne.s    opequal        if func <> 0 then equal is expected
  153. add?    cmpi.b    #"+",d1        is operator +,if so func = 1
  154.     bne.s    sub?
  155.     move.b    #1,func
  156.     bra    nextval
  157. sub?    cmpi.b    #"-",d1        is operator -,if so func = 2
  158.     bne.s    mult?
  159.     move.b    #2,func
  160.     bra    nextval
  161. mult?    cmpi.b    #"*",d1        is operator *,if so func = 3
  162.     bne.s    div?
  163.     move.b    #3,func
  164.     bra    nextval
  165. div?    cmpi.b    #"/",d1        is operator /,if so func = 4
  166.     bne.s    operr1
  167.     move.b    #4,func
  168.  
  169. nextval    move.l    #4,VarPtr    Point to next variable
  170.  
  171.     rts
  172.  
  173. operr1    ori    #%1,ccr        set carry if error only
  174.     andi    #%1,ccr
  175.     rts
  176.     
  177. opequal    cmpi.b    #"=",d1        is operator =, if so get result
  178.     beq    opeq
  179.     cmpi.b    #$0a,d1        is operator a return, if so get result
  180.     beq    opeq
  181.     bra    operr1        if not, error
  182.  
  183. opeq    moveq    #-1,d1
  184.  
  185.     rts
  186.  
  187. ;*************************************************************************
  188.  
  189. operr    lea    oInfo,a3    get start address of operator error info
  190.     bsr     nextlin        output message
  191.  
  192. ;*************************************************************************
  193.  
  194. error1    lea    Info,a3        get start address of information
  195.     bsr    nextlin        output message
  196.     bra    quit
  197.  
  198. ;*************************************************************************
  199.  
  200. nextlin    move.l    a3,d2        move start address to buffer (d2) of write
  201.     moveq    #0,d3        clear length input (d3) of write
  202.  
  203. mesloop    move.b    (a3)+,d1
  204.     beq.s    wrend        if null (0) all info has been output so end
  205.     addq    #1,d3        add 1 to length
  206.     cmpi.b    #$0a,d1        check to see if at end of line
  207.     bne.s    mesloop        if not get next character
  208.     
  209.  
  210. wrinfo    move.l    stdout,d1    stdout file handle
  211.     caldos    Write        Output line to standard output (screen)
  212.     bra.s    nextlin        Output next line of info
  213.  
  214. wrend    rts
  215.  
  216. ;*************************************************************************
  217.  
  218. getchar    move.l    ipadd,a0    get address of command line
  219.     move.w    iplen,d0    get length of command line
  220.  
  221. next_c    moveq    #0,d1        clear d1
  222.     move.b    (a0)+,d1    move next character to d1 and 
  223.                 ;increment address pointer
  224.     subq    #1,d0        decrement length counter    
  225.     cmpi.b    #$20,d1        is it a space
  226.     beq.s    next_c        get next character
  227.  
  228.     move.l    a0,ipadd    save current pionter to input address
  229.     move.w    d0,iplen    save length not read
  230.  
  231.     rts
  232.  
  233. ;*************************************************************************
  234.  
  235. oper    cmpi.b    #"+",d1        is the character an operator
  236.     beq.s    op1
  237.     cmpi.b    #"-",d1
  238.     beq.s    op1
  239.     cmpi.b    #"/",d1
  240.     beq.s    op1
  241.     cmpi.b    #"*",d1
  242.     beq.s    op1
  243.     cmpi.b    #"=",d1
  244.     beq.s    op1
  245.     cmpi.b    #$0a,d1
  246.     beq.s    op1
  247.     bra.s    opend
  248. op1    ori    #1,ccr        set carry bit if an operator
  249. opend    rts
  250.  
  251. ;******************************************************************
  252. ;*                                                                *
  253. ;*                   Input handling Routines                     *
  254. ;*                                                                *
  255. ;******************************************************************
  256.  
  257. ;******************************************************************
  258. ;*                                                                *
  259. ;*                  HEX Input handling Routine                    *
  260. ;*                                                                *
  261. ;******************************************************************
  262.  
  263. HEXip    bsr    getchar
  264.     bsr    oper        is the character an operator
  265.     bcc.s    Hno_op        if carry clear, character not an operator
  266.     andi    #0,ccr        clear carry before returning
  267.     rts
  268.  
  269. Hno_op    cmpi.b    #"0",d1        if input character is less than an ascii 0
  270.     blt    Herror        then in put is in error
  271.     cmpi.b    #$3a,d1        is in put character between ,including 0 - 9
  272.     blt.s    HEXnum        yes, do not subtract $37 from ascii value 
  273.  
  274. letter    cmpi.b    #"a",d1        is input greater than a
  275.     blt.s    letter2        is character a capital letter?
  276.     andi.b    #%11011111,d1    no, so convert to a capital
  277.  
  278. letter2    cmpi.b    #"A",d1        is input between and including A and F
  279.     blt    Herror
  280.     cmpi.b    #"F",d1
  281.     bgt    Herror        no, HEX number in error
  282.     subi.b    #$7,d1        yes, convert to a value between and including
  283.                 ; 3A and 3F
  284.  
  285. HEXnum    subi.b    #$30,d1        convert input to a value between 0 and F
  286.     lea    VarPtr,a0
  287.     move.l    0(a0),d0    move VarPtr to d0
  288.     move.l    4(a0,d0.w),d2    get current variable
  289.     moveq    #0,d3        clear counter register
  290. hshift    asl.l    #1,d2        shift left 4 bit places
  291.     bcs.s    Herror        if carry set number intered was to large
  292.     addq    #1,d3        inc counter
  293.     cmpi    #4,d3        shifted four places?
  294.     bne.s    hshift        no, repeat
  295.     or.l    d1,d2        yes, add input character to variable
  296.     move.l    d2,4(a0,d0.w)    save current variable
  297.     bra.s    HEXip        get next character
  298.  
  299. Herror    lea    hInfo,a3    get start address of operator error info
  300.     bsr     nextlin        output message
  301.     ori    #1,ccr        set carry to indicate an error
  302.     rts    
  303.  
  304. ;******************************************************************
  305. ;*                                                                *
  306. ;*                  OCT Input handling Routine                    *
  307. ;*                                                                *
  308. ;******************************************************************
  309.  
  310. OCTip    bsr    getchar
  311.     bsr    oper        is the character an operator
  312.     bcc.s    Ono_op        if carry clear, character not an operator
  313.     andi    #0,ccr        clear carry before returning
  314.     rts
  315.  
  316. Ono_op    subi.b    #$30,d1        remove ascii offset
  317.     blt.s    Oerror        if input character is less than an ascii 0
  318.                 ;then in put is in error
  319.     cmpi.b    #7,d1        is in put character between ,including 0 - 7
  320.     bgt.s    Oerror        no, error
  321.  
  322. OCTnum    lea    VarPtr,a0
  323.     move.l    0(a0),d0    move VarPtr to d0
  324.     move.l    4(a0,d0.w),d2    get current variable
  325.     moveq    #0,d3        clear counter register
  326. Oshift    asl.l    #1,d2        shift left three bit places
  327.     bcs.s    Oerror        if carry set number intered was to large
  328.     addq    #1,d3        inc counter
  329.     cmpi    #3,d3        shifted 3?
  330.     bne.s    Oshift        no, do it again
  331.     or.l    d1,d2        add input to variable
  332.     move.l    d2,4(a0,d0.w)    save current variable
  333.     bra.s    OCTip        get next character
  334.  
  335. Oerror    lea    OInfo,a3    get start address of operator error info
  336.     bsr     nextlin        output message
  337.     ori    #1,ccr        set carry to indicate an error
  338.     rts
  339.  
  340. ;******************************************************************
  341. ;*                                                                *
  342. ;*                  BIN Input handling Routine                    *
  343. ;*                                                                *
  344. ;******************************************************************
  345.  
  346. BINip    bsr    getchar
  347.     bsr    oper        is the character an operator
  348.     bcc.s    Bno_op        carry clear, character not an operator
  349.     andi    #0,ccr        clear carry before returning
  350.     rts
  351.  
  352. Bno_op    subi.b    #$30,d1        remove ascii offset
  353.     blt.s    Berror        if input character is less than an ascii 0
  354.                 ;then in put is in error
  355.     cmpi.b    #1,d1        is in put character 0 or 1
  356.     bgt.s    Berror        no, error
  357.  
  358. BINnum    lea    VarPtr,a0
  359.     move.l    0(a0),d0    move VarPtr to d0
  360.     move.l    4(a0,d0.w),d2    get current variable
  361. Bshift    asl.l    #1,d2        shift left one bit place
  362.     bcs.s    Berror        if carry set number intered was to large
  363.     or.l    d1,d2        add input to variable
  364.     move.l    d2,4(a0,d0.w)    save current variable
  365.     bra.s    BINip        get next character
  366.  
  367. Berror    lea    BInfo,a3    get start address of operator error info
  368.     bsr     nextlin        output message
  369.     ori    #1,ccr        set carry to indicate an error
  370.     rts
  371.  
  372. ;******************************************************************
  373. ;*                                                                *
  374. ;*                  DEC Input handling Routine                    *
  375. ;*                                                                *
  376. ;******************************************************************
  377.  
  378. DECip    bsr    getchar
  379.     bsr    oper        is the character an operator
  380.     bcc.s    Dno_op        carry clear, character not an operator
  381.     tst.b    neg        test neg flag is set
  382.     beq.s    DECpos        if operator is "-" and neg flag clear,return
  383.     bsr.s    DECneg        if neg flaf set, make number negative
  384. DECpos    andi    #0,ccr        clear carry defore returning
  385.     rts
  386.  
  387. DECneg    lea    VarPtr,a0    if negative
  388.     move.l    0(a0),d0    move VarPtr to d0
  389.     move.l    4(a0,d0.w),d2    get current variable
  390.     neg.l    d2        make it negative
  391.     move.l    d2,4(a0,d0.w)    save current variable
  392.     clr.b    neg        clear negative flag
  393.     rts
  394.  
  395. Dno_op    subi.b    #$30,d1        remove ascii offset
  396.     blt.s    Derror        if input character is less than an ascii 0
  397.                 ;then in put is in error
  398.     cmpi.b    #9,d1        is in put character between, including 0 or 9
  399.     bgt.s    Derror        no, error
  400.  
  401. DECnum    lea    VarPtr,a0
  402.     move.l    0(a0),d0    move VarPtr to d0
  403.     move.l    4(a0,d0.w),d2    get current variable
  404.     move.l    d2,d3        mult by 10
  405.     asl.l    #1,d3        *2
  406.     bvs.s    Derror        if ovrflow input dec number is to large
  407.     move.l    d3,d4        save * 2 result
  408.     asl.l    #2,d3        *4, total of *8
  409.     bvs.s    Derror        if ovrflow input dec number is to large
  410.     add.l    d3,d4        add *2 result to *8 result
  411.     bmi.s    Derror        if becomes neg input dec number is to large
  412.     add.l    d1,d4        add input to value
  413.     move.l    d4,4(a0,d0.w)    save current variable
  414.     bra.s    DECip        get next character
  415.  
  416. Derror    lea    DInfo,a3    get start address of operator error info
  417.     bsr     nextlin        output message
  418.     ori    #1,ccr        clear carry before returning
  419.     rts
  420.  
  421. ;******************************************************************
  422. ;*                                                                *
  423. ;*                    Math Handling Routines                      *
  424. ;*                                                                *
  425. ;******************************************************************
  426.  
  427. ;******************************************************************
  428. ;*                                                                *
  429. ;*                         ADD Routine                            *
  430. ;*                                                                *
  431. ;******************************************************************
  432.  
  433. add    lea    VarPtr,a0
  434.     lea    Total,a1
  435.     moveq    #0,d1
  436.     move.l    0(a0),d0    move VarPtr to d0
  437.     move.l    4(a0),d2    move Var1 to d2
  438.     move.l    4(a0,d0.w),d3    move Var2 to d3
  439.     add.l    d3,d2        add variables
  440.     svs    err        if over flow, err = -1
  441.     bvc.s    addok        if add ok, save result and output 
  442.     lea    adderrI,a3    no, output error
  443.     bsr    nextlin
  444.     bra    addend
  445. addok    move.l    d1,(a1)        save result
  446.     move.l    d2,4(a1)
  447.     
  448. addend    rts
  449.  
  450. ;******************************************************************
  451. ;*                                                                *
  452. ;*                         SUB Routine                            *
  453. ;*                                                                *
  454. ;******************************************************************
  455.  
  456. sub    lea    VarPtr,a0
  457.     lea    Total,a1
  458.     moveq    #0,d1
  459.     move.l    0(a0),d0    move VarPtr to d0
  460.     move.l    4(a0),d2    move Var1 to d2
  461.     move.l    4(a0,d0.w),d3    move Var2 to d3
  462.     sub.l    d3,d2        var1 - var2
  463.     svs    err        if over flow, err = -1
  464.     bvc.s    subok        sub ok, save reult and output
  465.     lea    suberrI,a3    no, output error message
  466.     bsr    nextlin
  467.     bra    subend
  468. subok    move.l    d1,(a1)        save result
  469.     move.l    d2,4(a1)
  470.     
  471. subend    rts
  472.  
  473. ;******************************************************************
  474. ;*                                                                *
  475. ;*                         MULT Routine                           *
  476. ;*                         32 * 32 = 64                           *
  477. ;*                                                                *
  478. ;******************************************************************
  479.  
  480. mult    lea    VarPtr,a0
  481.     lea    Total,a1    a1 points to result storage area
  482.     move.l    0(a0),d0    move VarPtr to d0
  483.     move.l    4(a0),d1    move Var1 to d1
  484.     move.l    4(a0,d0.w),d2    move Var2 to d2
  485.     move.l    d1,d6        copy var1 to d6
  486.     move.l    d2,d7        copy var2 to d7
  487.  
  488. mul32    move.l    d1,d3        copy var1 to d3
  489.     move.l    d1,d4        and into d4
  490.     swap    d4        swaped form (upper 2 bytes swapped with lower)    
  491.     move.l    d2,d5        copy var2 to d5
  492.     swap    d5        in swapped form
  493.     mulu    d2,d1        partial product    #1
  494.     mulu    d4,d2                #2
  495.     mulu    d5,d3                #3
  496.     mulu    d5,d4                #4
  497.     swap    d1        sum1 = pp #2 low +
  498.     add    d2,d1        pp #1 high
  499.     clr.l    d5
  500.     addx.l    d5,d4        propagate carry into pp #4
  501.     add    d3,d1        sum2 = sum1 + pp #3 low
  502.     addx.l    d5,d4        propargate carry into pp #4
  503.     swap    d1        put low product in correct order
  504.     clr    d2        prepare for sum #3
  505.     swap    d2
  506.     clr    d3
  507.     swap    d3
  508.     add.l    d3,d2        sum3 = pp #2 low + pp #3 high
  509.     add.l    d4,d2        sum4 = sum3 + pp #4
  510.  
  511. ;
  512. ;    The following instructions modify the product if required
  513. ;
  514.  
  515.     tst.l    d7        val2 negative?
  516.     bpl.s    CHKd6        no, go check val1
  517.     sub.l    d6,d2        yes, sub val1 from product
  518.  
  519. CHKd6    tst.l    d6        val1 negative
  520.     bpl.s    mulend        no, finish
  521.     sub.l    d7,d2        yes, sub val2 from product
  522.  
  523. mulend    move.l    d2,(a1)        save result, high 32 bits
  524.     move.l    d1,4(a1)    low 32bits
  525.     
  526.     rts
  527.  
  528. ;******************************************************************
  529. ;*                                                                *
  530. ;*                         DIV Routines                           *
  531. ;*                                                                *
  532. ;******************************************************************
  533.  
  534. div    lea    VarPtr,a0
  535.     lea    Total,a1    a1 points to result storage error
  536.     move.l    0(a0),d0    move VarPtr to d0
  537.     move.l    4(a0),d2    move Var1 to d2
  538.     move.l    4(a0,d0.w),d1    move Var2 to d1
  539.  
  540. div0    moveq    #0,d6
  541.     moveq    #0,d7
  542.     tst.l    d1        is var2 negative or zero
  543.     seq    err        if zero, divid by zero
  544.     beq.s    dbyz        and output message
  545.     smi    d6        set d6 if var2 is negative
  546.     bpl.s    div1        positive, test next variable
  547.     neg.l    d1        make var2 positive
  548. div1    tst.l    d2        is var1 negative
  549.     smi    d7        set d7 if var1 is negative
  550.     bpl.s    div2        positive, divid var1 by var2
  551.     neg.l    d2        make var1 positive
  552. div2    eor    d6,d7        are signs different
  553.     sne.b    neg        if signs are different result must be neg
  554.  
  555.     cmpi.l    #$FFFF,d1    is var2 larger than 16 bits
  556.     sls    d6        if lower or same set d6 to -1
  557.     addi.b    #1,d6        calculate jump offset
  558.     lsl.l    #2,d6        *4 to get address
  559.     lea    divlen,a3    get address of jump table
  560.     move.l    0(a3,d6.w),a3    move address of divid routine to a3
  561.     jsr    (a3)
  562.  
  563. divend    move.l    d2,(a1)        quotient
  564.     move.l    d1,4(a1)    remainder
  565.     
  566.     rts
  567.  
  568. divlen    dc.l    d32.16,d32.32
  569.  
  570. dbyz    lea    dbyzI,a3    output divid by zero message
  571.     bsr    nextlin
  572.     rts
  573. ;
  574. ;    Use this routine if var2 is stored in 16 bits or less
  575. ;    Uses 68000 divid operand and accounts for over flow when the quotient
  576. ;    needs 32 bits instead of the standard 16
  577. ;
  578.  
  579. ;    d2 = dividend
  580. ;    d1 = divisor
  581.  
  582. d32.16    moveq    #0,d4
  583.     divu    d1,d2        Has overflow occurred?
  584.     bvc.s    dformat        No, go format result
  585.     move.l    d2,d3        Yes, copy yo into d3
  586.     clr.w    d2        clr low word of d2, y1-y0 to y1-0
  587.     swap    d2        y1-0 to 0-y1
  588.     divu    d1,d2        div puts r1-q1 into d2
  589.     move    d2,d4        d3 contains q1
  590.     move    d3,d2        d1 changes from r1-q1 to r1-y0
  591.     divu    d1,d2        div puts r0-q0 into d1
  592.  
  593. ;
  594. ;    Form quotient (D2) and remainder (D1)
  595. ;
  596.  
  597. dformat    move.l    d2,d1        d1 contains r-q or r0-q0
  598.     swap    d2        d2 contains q-r or q0-r0
  599.     move    d4,d2        d2 contains q-0 or q0-q1
  600.     swap    d2        d2 contains 0-q or q1-q0
  601.     clr    d1        d1 contains r-0 or r0-0
  602.     swap    d1        d1 contains 0-r or 0-r0
  603.  
  604.     tst.b    neg        is result to be negative
  605.     beq.s    d32.16e        no, return
  606.     neg.l    d2        yes, make neqative
  607.     neg.l    d1
  608.     clr.b    neg
  609.  
  610. d32.16e    rts
  611.  
  612. ;
  613. ;    Use this routine if var2 is stored in 16 bits or less
  614. ;    Uses a divid algorithm
  615.  
  616. ;
  617. ;    d2 = dividend
  618. ;    d1 = divisor
  619. ;
  620.  
  621. d32.32    cmp.l    d2,d1        divisor = dividend
  622.     bne.s    divi1        no, divid out
  623.     moveq    #1,d3        yes, result = 1
  624.     moveq    #0,d2        zero remainder
  625.     bra.s    divout        return
  626.  
  627. divi1    cmp.l    d2,d1        dividend > divisor?
  628.     bcs.s    divi2        yes, result is > 0
  629.     moveq    #0,d3        else result = 0 + r        
  630.     bra.s    divout        return
  631.  
  632. divi2    moveq    #0,d4        initialise iteration count
  633.  
  634. divi3    addq    #1,d4        inc count
  635.     asl.l    #1,d1        see if d1 goes > 0
  636.     bmi.s    divi4        it did if now neg
  637.     cmp.l    d1,d2        d1 > 0
  638.     bcc.s    divi3        no, try again
  639.  
  640. divi4    lsr.l    #1,d1        readjust divisor
  641.     moveq    #0,d3        initialise quotient
  642.  
  643. divi5    sub.l    d1,d2        divisor goes in
  644.     bmi.s    divi6        no
  645.     addq    #1,d3        else record it
  646.     bra.s    divi7        
  647.  
  648. divi6    add.l    d1,d2        restore dividend
  649.  
  650. divi7    subq    #1,d4        done all bits?
  651.     beq.s    divout        yes
  652.     asl.l    #1,d3        quotient * 2
  653.     asr.l    #1,d1        divisor / 2
  654.     bra.s    divi5        next round
  655.  
  656. divout    move.l    d2,d1        move remainder to d1
  657.     move.l    d3,d2        move quotient to result
  658.     tst.b    neg        should result be neg
  659.     beq.s    d32.32e        no exit        
  660.     neg.l    d2        change sign of result
  661.     neg.l    d1
  662.     clr.b    neg
  663.  
  664. d32.32e    rts
  665.  
  666.  
  667. ;******************************************************************
  668. ;*                                                                *
  669. ;*                   Output Handling Routines                     *
  670. ;*                                                                *
  671. ;******************************************************************
  672.  
  673. ;******************************************************************
  674. ;*                             HtoA                               *
  675. ;*           Converts variable pointed to by VarPtr to            *
  676. ;*               a HEX ascii string for displaying.               *
  677. ;******************************************************************
  678.  
  679. HtoA    lea    VarPtr,a0
  680.     move.l    #12,d4        point to result
  681.     lea    BuffT,a1    get address of tempory buffer
  682.     move.l    #147,d3        point to end of buffer
  683.  
  684. GetH    move.l    4(a0,d4),d0    get a varible
  685.  
  686.     cmpi.b    #12,d4        pointing to result
  687.     blt.s    GetH0        no, no special trement
  688.     cmpi.b    #4,func        is operation div
  689.     beq.s    Hdiv        yes, output in divid format
  690.  
  691. GetH0    cmpi    #8,d4        remove if leading zeros are to be removed
  692.     bne.s    GetH1                "
  693.     tst.l    d0                "
  694.     bne.s    GetH1                "
  695.     subq    #4,d4                "
  696.     bsr    Iequal                "
  697.     bra.s    GetH                "
  698.     
  699. GetH1    bsr    HtoAt        change variable  to ascii in HEX base
  700.     tst.b    err        error in converstion
  701.     bne.s    HtoAerr        output error message
  702.  
  703. nextH    subq    #4,d4        point to next variable
  704.     bmi.s    BTtoBH        if negative all variables actioned
  705.     beq.s    Hoper        d4 = 0, then output relavent operator
  706.  
  707. Hequal    cmpi    #4,d4        has total been actioned
  708.     bhi.s    GetH        higher, get high 32 bits of result
  709.     bsr    Iequal        d4 = 4, insert "=" sign
  710.     bra.s    GetH        get next variable
  711.  
  712. Hoper    bsr    Ifunc        branch to insert operator routine 
  713.     bra    GetH        get next variable
  714.  
  715. BTtoBH    lea    BuffH,a0    a0 points to HEX output buffer
  716.     ;jsr    Rled0        remove leading zeros
  717.     jsr    BTcopy        do not remove leading zeros
  718.     rts
  719.  
  720. Hdiv    move.l    #9,d5        insert "remainder" into tempory buffer
  721.     lea    rem,a2        a2 points to remainder
  722. Hdiv1    move.b    0(a2,d5.w),d6    get a letter
  723.     move.b    d6,0(a1,d3.w)    put it into tempory buffer
  724.     subq    #1,d3        point to next letter
  725.     dbf    d5,Hdiv1    d5 = 0, then finished
  726.  
  727. Hdiv2    bsr    HtoAt        convet to ascii, HEX base
  728.     move.b    #' ',0(a1,d3.w)    add "+" to buffer
  729.     subq    #1,d3
  730.     move.b    #'+',0(a1,d3.w)
  731.     subq    #1,d3
  732.     move.b    #' ',0(a1,d3.w)
  733.     subq    #1,d3
  734.     subq    #4,d4        point to quotient
  735.     move.l    4(a0,d4.w),d0    get quotient
  736.  
  737.     bsr    HtoAt        convert to ascii, HEX base
  738.     bra    nextH        get var2
  739.  
  740.  
  741. HtoAerr    lea    HtoAI,a3    output error message
  742.     bsr    nextlin
  743.     rts
  744.  
  745.  
  746. HtoAt    moveq    #8,d1        do not remove leading zeros
  747.                 ;move to remove leading zeros
  748.  
  749. HtoAtp    move.l    d0,d2
  750.     andi.l    #$0000000F,d2    get lsnibble
  751.     addi.l    #$30,d2        ascii offset for num
  752.     cmpi.l    #$39,d2        larger than $39
  753.     ble.s    HtoAct        no do not add $7, yes, add $7
  754.     addq.l    #$7,d2        ascii offset for alpha
  755. HtoAct    move.b    d2,0(a1,d3.w)    move to tempory buffer
  756.     subq    #1,d3        point to next buffer place
  757.     lsr.l    #4,d0        move next byte into LSnibble
  758.     
  759.     subq    #1,d1        decrememt counter, remove to delete leading
  760.                 ;zero
  761.     smi.b    err        if negative, an error has occurred
  762.     bgt.s    HtoAtp        if greater convert next byte
  763.     
  764.     rts
  765.     
  766. ;******************************************************************
  767. ;*                             OtoA                               *
  768. ;*           Converts variable pointed to by VarPtr to            *
  769. ;*               a OCT ascii string for displaying.               *
  770. ;******************************************************************
  771.  
  772. OtoA    lea    VarPtr,a0
  773.     move.l    #12,d4        point to result
  774.     lea    BuffT,a1    get address of tempory buffer
  775.     move.l    #147,d3        point to end of buffer
  776.  
  777. GetO    move.l    4(a0,d4),d0    get a varible
  778.  
  779.     cmpi.b    #12,d4        pointing to result
  780.     blt.s    GetO0        no, no special treatment
  781.     cmpi.b    #4,func        is operation div
  782.     beq.s    Odiv        yes, output in divid format
  783.     
  784. GetO0    cmpi    #8,d4        remove if leading zeros are to be removed
  785.     bne.s    GetO1                "
  786.     tst.l    d0                "    
  787.     bne.s    GetO1                "
  788.     subq    #4,d4                "
  789.     bsr    Iequal                "    
  790.     bra.s    GetO                "                "
  791.     
  792. GetO1    bsr    OtoAt        change variable  to ascii in OCT base
  793.     tst.b    err        error in converstion
  794.     bne.s    OtoAerr        output error message
  795.  
  796. nextO    subq    #4,d4        point to next variable
  797.     bmi.s    BTtoBO        if negative all variables actioned
  798.     beq.s    Ooper        d4 = 0, then output relavent operator
  799.  
  800. Oequal    cmpi    #4,d4        has total been actioned
  801.     bhi.s    GetO        higher, get high 32 bits of result
  802.     bsr    Iequal        d4 = 4, insert "=" sign
  803.     bra.s    GetO        get next variable
  804.  
  805. Ooper    bsr    Ifunc        branch to insert operator routine
  806.     bra    GetO        get next variable
  807.  
  808. BTtoBO    lea    BuffO,a0    a0 points to OCT output buffer
  809.     ;jsr    Rled0        remove leading zeros
  810.     jsr    BTcopy        do not remove leading zeros
  811.     rts
  812.  
  813. Odiv    move.l    #9,d5        insert "remainder" into tempory buffer
  814.     lea    rem,a2        a2 points to remainder
  815. Odiv1    move.b    0(a2,d5.w),d6    get a letter
  816.     move.b    d6,0(a1,d3.w)    put it into tempory buffer
  817.     subq    #1,d3        point to next letter
  818.     dbf    d5,Odiv1    d5 = 0, then finished
  819.  
  820. Odiv2    bsr    OtoAt        convet to ascii, BIN base
  821.     move.b    #' ',0(a1,d3.w)    if so add + to buffer
  822.     subq    #1,d3
  823.     move.b    #'+',0(a1,d3.w)
  824.     subq    #1,d3
  825.     move.b    #' ',0(a1,d3.w)
  826.     subq    #1,d3
  827.     subq    #4,d4        point to quotient
  828.     move.l    4(a0,d4.w),d0    get quotient
  829.  
  830.     bsr    OtoAt        convert to ascii, OCT base
  831.     bra    nextO        get var2
  832.  
  833. OtoAerr    lea    HtoAI,a3    output error message
  834.     bsr    nextlin
  835.     rts
  836.  
  837. OtoAt    moveq    #11,d1        do not remove leading zeros
  838.                 ;move to remove leading zeros
  839.  
  840. OtoAtp    move.l    d0,d2
  841.     andi.l    #$00000007,d2    get lsf
  842.     addi.l    #$30,d2        ascii offset for num
  843.  
  844. OtoAct    move.b    d2,0(a1,d3.w)    move to tempory buffer
  845.     subq    #1,d3        point to next buffer place
  846.     lsr.l    #3,d0        move next byte into LSBits (3)
  847.  
  848.     subq    #1,d1        decrememt counter, remove to delete leading
  849.                 ;zeros
  850.     smi    err        if negative, an error has occurred
  851.     bgt.s    OtoAtp        if greater convert next 3 bits
  852.     
  853.     rts
  854.  
  855. ;******************************************************************
  856. ;*                             BtoA                               *
  857. ;*           Converts variable pointed to by VarPtr to            *
  858. ;*               a BIN ascii string for displaying.               *
  859. ;******************************************************************
  860.  
  861. BtoA    lea    VarPtr,a0
  862.     move.l    #12,d4        point to result
  863.     lea    BuffT,a1    get address of tempory buffer
  864.     move.l    #147,d3        point to end of buffer
  865.  
  866. GetB    move.l    4(a0,d4),d0    get a varible
  867.  
  868.     cmpi.b    #12,d4        pointing to result
  869.     blt.s    GetB0        no, no special treatment
  870.     cmpi.b    #4,func        is operation div
  871.     beq.s    Bdiv        yes, output in divid format
  872.  
  873. GetB0    cmpi    #8,d4        remove if leading zeros are to be removed
  874.     bne.s    GetB1                "
  875.     tst.l    d0                "
  876.     bne.s    GetB1                "
  877.     subq    #4,d4                "
  878.     bsr    Iequal                "
  879.     bra.s    GetB                "                "
  880.     
  881. GetB1    bsr    BtoAt        change variable  to ascii in BIN base
  882.     tst.b    err        error in converstion
  883.     bne.s    BtoAerr        output error message    
  884.  
  885. nextB    subq    #4,d4        point to next variable
  886.     bmi.s    BTtoBB        if negative all variables actioned
  887.     beq.s    Boper        d4 = 0, then output relavent operator
  888.  
  889. Bequal    cmpi    #4,d4        has total been actioned
  890.     bhi.s    GetB        higher, get high 32 bits of result
  891.     bsr    Iequal        d4 = 4, insert "=" sign
  892.     bra.s    GetB        get next variable
  893.  
  894. Boper    bsr    Ifunc        branch to insert operator routine
  895.     bra    GetB        get next variable
  896.  
  897. BTtoBB    lea    BuffB,a0    a0 points to BIN output buffer
  898.     ;jsr    Rled0        remove leding zeros
  899.     jsr    BTcopy        do not remove leading zeros
  900.     rts
  901.  
  902. Bdiv    move.l    #9,d5        insert "remainder" into tempory buffer
  903.     lea    rem,a2        a2 points to remainder
  904. Bdiv1    move.b    0(a2,d5.w),d6    get a letter
  905.     move.b    d6,0(a1,d3.w)    put it into tempory buffer
  906.     subq    #1,d3        point to next letter
  907.     dbf    d5,Bdiv1    d5 = 0, then finished
  908.  
  909. Bdiv2    bsr    BtoAt        convet to ascii, BIN base
  910.     move.b    #' ',0(a1,d3.w)    if so add + to buffer
  911.     subq    #1,d3
  912.     move.b    #'+',0(a1,d3.w)
  913.     subq    #1,d3
  914.     move.b    #' ',0(a1,d3.w)
  915.     subq    #1,d3
  916.     subq    #4,d4        point to quotient
  917.     move.l    4(a0,d4.w),d0    get quotient
  918.  
  919.     bsr    BtoAt        convert to ascii, BIN base
  920.     bra    nextB        get var2
  921.  
  922. BtoAerr    lea    HtoAI,a3    output error message
  923.     bsr    nextlin
  924.     bra    quit
  925.  
  926. BtoAt    move.l    #32,d1        do not remove leading zeros
  927.                 ;move to remove leading zeros
  928.  
  929.  
  930. BtoAtp    move.l    d0,d2
  931.     andi.l    #$00000001,d2    get lsbit
  932.     addi.l    #$30,d2        ascii offset for num
  933.  
  934. BtoAct    move.b    d2,0(a1,d3.w)    move to tempory buffer
  935.     subq    #1,d3        point to next buffer place
  936.     lsr.l    #1,d0        move next byte into LSBit
  937.  
  938.     subq    #1,d1        decrememt counter, remove to delete leading
  939.                 ;zeros
  940.     smi    err        if negative, an error has occurred
  941.     bgt.s    BtoAtp        if greater convert next bit
  942.     
  943.     rts
  944.  
  945. ;******************************************************************
  946. ;*                              DtoA                              *
  947. ;*           Converts variable pointed to by VarPtr to            *
  948. ;*               a DEC ascii string for displaying.               *
  949. ;******************************************************************
  950.  
  951. DtoA    lea    VarPtr,a0
  952.     move.l    #12,d4        point to result
  953.     lea    BuffT,a1    get address of tempory buffer
  954.     move.l    #147,d3        point to end of buffer
  955.     
  956.  
  957. GetD    move.l    4(a0,d4.w),d0    get a variable
  958.     cmpi.b    #12,d4        pointing to result
  959.     blt.s    GetD0        no, no special treatment
  960.     cmpi.b    #3,func        is operation mult or div
  961.     beq    Dtmul        if equal, output in mult format
  962.     bgt    Dtdiv        if greater, output in div format
  963. GetD0    tst.l    d0        find sign of variable
  964.     bge.s    GetD1
  965.     smi    neg        neg, set neg flag 
  966.     neg.l    d0        make number possible
  967. GetD1    bsr    HtoBCD        change variable  to ascii in DEC base
  968.     
  969.  
  970. nextD    subq    #4,d4        point to next variable
  971.     bmi    BTtoBD        if negative all variables actioned
  972.     beq.s    Doper        d4 = 4, then insert operator
  973.  
  974. Dequal    cmpi    #4,d4        has total been actioned
  975.     bhi.s    Getr        no, go to save to buffer routine
  976.     bsr    DequalI        yes, insert "=" in tempory buffer
  977.     bra.s    GetD        get next variable
  978.  
  979. Getr    bsr    DtoAct        move result from DecTemp to Tempory Buffer
  980.     subq    #4,d4        point to next variable
  981.     bsr    Iequal        insert "=" into tempory buffer
  982.     bra    GetD        get next variable
  983.  
  984. Doper    bsr    DtoAct        move var2 from DecTemp to Tempory Buffer
  985.     bsr    Ifunc        then insert operator
  986.     bra    GetD        get var1
  987.  
  988. DequalI    bsr    DtoAct        move result from DecTemp to Tempory Buffer
  989.     bsr    Iequal        then insert equal sign
  990.     rts
  991.  
  992. BTtoBD    bsr    DtoAct        move DecTemp to Buffer
  993.     lea    BuffD,a0    point to DEC output buffer
  994.     jsr    Rled0        remove leading zero's and move to output buffer
  995.     rts
  996.  
  997. ;    Dtmul uses two longwords to calculate decimal equivalent
  998.  
  999. Dtmul    tst.l    0(a0,d4.w)    is variable negative
  1000.     bge.s    Dtmul1        no, convert
  1001.     smi    neg        yes, set neg flag
  1002.     neg.l    d0        neg low word
  1003.     negx.l    0(a0,d4.w)    neg (account for borrow if used for low word)
  1004. Dtmul1    bsr    HtoBCD        change variable  to ascii in DEC base
  1005.     subq    #4,d4        point to next variable
  1006.     move.l    4(a0,d4.w),d0    get high 32 bits
  1007.     bsr    BCDT        miss out set up routine in HtoBCD
  1008.     bra    nextD        move to tempory buffer and get next var2
  1009.  
  1010. ;    Dtdiv uses the lowword for remainder, high word for quotient
  1011.  
  1012. Dtdiv    move.l    #9,d5        insert "remainder" into tempory buffer
  1013.     lea    rem,a2        a2 points to remainder
  1014. Dtdiv1    move.b    0(a2,d5.w),d6    get a letter
  1015.     move.b    d6,0(a1,d3.w)    put it into tempory buffer
  1016.     subq    #1,d3        point to next letter
  1017.     dbf    d5,Dtdiv1    d5 = 0, then finished
  1018.     tst.l    d0        is remainder negative
  1019.     bpl.s    Dtdiv2        no, convert
  1020.     smi    neg        yes, set neg flag
  1021.     neg.l    d0        and make poitive
  1022. Dtdiv2    bsr    HtoBCD        change variable  to ascii in DEC base
  1023.     bsr    DtoAct        move to tempory buffer
  1024.     tst.b    neg        was number negative
  1025.     bpl.s    Dtdiv3        no, add "+" to buffer
  1026.     move.b    #' ',0(a1,d3.w)    yes, so add - to buffer
  1027.     subq    #1,d3
  1028.     move.b    #'-',0(a1,d3.w)
  1029.     subq    #1,d3
  1030.     move.b    #' ',0(a1,d3.w)
  1031.     subq    #1,d3
  1032.     clr.b    neg        clear neg flag
  1033.     bra.s    Dtdiv4        convert quotient
  1034. Dtdiv3    move.b    #' ',0(a1,d3.w)    add + to buffer
  1035.     subq    #1,d3
  1036.     move.b    #'+',0(a1,d3.w)
  1037.     subq    #1,d3
  1038.     move.b    #' ',0(a1,d3.w)
  1039.     subq    #1,d3
  1040. Dtdiv4    subq    #4,d4        point to next variable
  1041.     move.l    4(a0,d4.w),d0    get quotient
  1042.     tst.l    d0        is it negative
  1043.     smi.b    neg        set neg flag if negative
  1044.     bpl.s    Dtdiv5        no, convert
  1045.     neg.l    d0        yes, make it positive
  1046. Dtdiv5    bsr    HtoBCD        change variable  to ascii in BIN base
  1047.     bra    nextD        move to tempory buffer and get var2
  1048.  
  1049. ;    HtoBCD converts a HEX number to BCD
  1050.  
  1051. HtoBCD    moveq    #0,d5        clear d5
  1052.     move.l    #DecSize,d2    get size of DecTemp    
  1053.     lea    DecTemp,a2    get address of DecTemp
  1054. HtoBCD2    move.b    d5,0(a2,d2.w)    clear a2 + d2
  1055.     dbmi.w    d2,HtoBCD2    all done, no do it again
  1056.     lea    DecCon1,a2    get address of DecCon1
  1057.  
  1058. BCDT    moveq    #8,d1        d1 holds the number of nibbles to do
  1059.  
  1060. BCDT0    move.l    d0,d2        move variable to d2
  1061.     andi.l    #$0000000F,d2    get lsnibble
  1062.  
  1063. BCDT1    beq.s    BCDT3        if zero get next significant nibble
  1064.     lea    DecCon0,a4    get address of DecCon0
  1065.     andi    #$EF,ccr    clear extended flag in ccr
  1066.     move.l    a2,a3
  1067.     adda.l    d5,a3        calculate 16^x pointer
  1068.  
  1069. BCDT2    abcd    -(a3),-(a4)    add BCD from number pointed to by a3 to DecTemp
  1070.     cmpa.l    #DecTemp,a4    all bytes added
  1071.     bne.s    BCDT2        no, do next byte, elseget next significant nib
  1072.     subq    #1,d2        sub 1 from hex number
  1073.     bra    BCDT1        do again
  1074.  
  1075. BCDT3    lsr.l    #4,d0        move next significant nibble into lsnibble
  1076.     addi.l    #12,d5        point to next 16^x (x = D5)
  1077.     subq    #1,d1        dec nibble count
  1078.     bne.s    BCDT0        if not zero do it again
  1079.  
  1080. BCDend    rts    
  1081.     
  1082. ;    DtoAct converts a BCD number to ASCII and moves it to a tempory buffer
  1083.  
  1084. DtoAct    lea    DecCon0,a4    point to end of DecTemp
  1085. DtoAct1    moveq    #2,d5        d5 = nibble count
  1086.     move.b    -(a4),d0    move byte from DecTemp into d0
  1087. DtoAct2    move.b    d0,d2        
  1088.     andi    #$F,d2        get lsnibble
  1089.     add.b    #$30,d2        convert it to an ascii number
  1090.     move.b    d2,0(a1,d3.w)    move to tempory buffer
  1091.     subq    #1,d3        point to next buffer position
  1092.     lsr    #4,d0        move nibble into lsnibble position
  1093.     subq    #1,d5        dec nibble count
  1094.     bne.s    DtoAct2        all nibbles done, no do next nibble
  1095.  
  1096. DtoAct3    cmpa.l    #DecTemp-1,a4    else, all of DecTemp done?
  1097.     bne.s    DtoAct1        no, done next byte
  1098.     tst.b    neg        was number negative
  1099.     beq.s    DtoActe        no return
  1100.     move.b    #'-',0(a1,d3.w)    else put negative in front of number
  1101.     subq    #1,d3        point to next buffer position
  1102.     clr.b    neg        clear neg flag
  1103. DtoActe    rts
  1104.  
  1105. DtoAerr    lea    HtoAI,a3    print error message
  1106.     bsr    nextlin
  1107.     rts
  1108.  
  1109. ***********************************************************
  1110.  
  1111. Iequal    move.b    #' ',0(a1,d3.w)    add " = " to buffer
  1112.     subq    #1,d3
  1113.     move.b    #'=',0(a1,d3.w)
  1114.     subq    #1,d3
  1115.     move.b    #' ',0(a1,d3.w)
  1116.     subq    #1,d3
  1117.     rts
  1118.  
  1119. Ifunc    move.b    #' ',0(a1,d3.w)    add function to buffer
  1120.     subq    #1,d3
  1121.     moveq    #0,d5
  1122.     move.b    func,d5
  1123.     subq    #1,d5
  1124.     lsl    #2,d5        cal index for jump table
  1125.     lea    funcH,a3    get address of jump table
  1126.     move.l    0(a3,d5.w),a3    get address of func routine
  1127.     jsr    (a3)        insert correct function
  1128.     move.b    #' ',0(a1,d3.w)
  1129.     subq    #1,d3
  1130.     rts
  1131.  
  1132. funcH    dc.l    Iadd,Isub,Imult,Idiv
  1133.  
  1134. Iadd    move.b    #'+',0(a1,d3.w)    add + to buffer
  1135.     subq    #1,d3
  1136.     rts
  1137.  
  1138. Isub    move.b    #'-',0(a1,d3.w)    add - to buffer
  1139.     subq    #1,d3
  1140.     rts
  1141.  
  1142. Imult    move.b    #'*',0(a1,d3.w)    add * to buffer
  1143.     subq    #1,d3
  1144.     rts
  1145.  
  1146. Idiv    move.b    #'/',0(a1,d3.w)    add / to buffer
  1147.     subq    #1,d3
  1148.     rts
  1149.  
  1150. ;******************************************************************
  1151. ;*                   Rmzero  Kill leading zeros                   *
  1152. ;*           Inputs: a0 pointer to destination buffer             *
  1153. ;*                   a1 pointer to source                         *
  1154. ;******************************************************************
  1155.  
  1156. Rled0    moveq    #0,d0
  1157.     moveq    #0,d2
  1158.     moveq    #0,d1
  1159.     addq    #1,d3        compensate for last subq of d3
  1160. Rled01    move.b    0(a1,d3.w),d0    get character from buffer
  1161.     addq    #1,d3
  1162.     cmpi.b    #$30,d0        is it a zero
  1163.     bne.s    Rled02        check for other characters of interest
  1164.     tst    d1        has a character been output
  1165.     beq.s    Rled01        no, geet next character
  1166.     bne.s    BtoB2        yes, output "0"
  1167.         
  1168. Rled02    cmpi.b    #$20,d0        is the character a space
  1169.     beq.s    BtoB        yes, check if input betwwen spaces
  1170.     cmpi    #'-',d0        is it "-"?
  1171.     beq.s    BtoB3        move it to out put buffer
  1172.     cmpi.b    #LF,d0        end of tempory buffer
  1173.     bne.s    BtoB2        no, put character into buffer
  1174.     tst    d1        character between last space and Line Feed
  1175.     bne    Tnzero        yes, put into buffer
  1176.     move.b    #'0',0(a0,d2.w)    no, insert a "0" before Line Feed
  1177.     addq    #1,d2
  1178.     moveq    #LF,d0
  1179. Tnzero    move.b    d0,0(a0,d2.w)    move to output buffer
  1180.     addq    #1,d2        inc output buffer pointer
  1181.     move.b    #0,0(a0,d2.w)    put a NULL at end of output string
  1182.     rts
  1183.  
  1184.     
  1185. BtoB    tst    d1        has a character been output
  1186.     beq.s    Val0        no, insert a "0"
  1187.     moveq    #3,d1        yes, d1 is used to count three characters
  1188.                 ;move " ? " to output buffer. (? = +,-,*,/,=)
  1189. BtoB1    move.b    d0,0(a0,d2.w)    move character to output buffer
  1190.     addq    #1,d2        inc buffer pointer
  1191.     subq    #1,d1        dec character counter
  1192.     beq.s    BtoB1e        all done, reset character output flag
  1193.     move.b    0(a1,d3.w),d0    get character from temp buffer
  1194.     addq    #1,d3        inc buffer pointer
  1195.     bra    BtoB1        do again
  1196.  
  1197. BtoB1e    moveq    #0,d1        clear output flag
  1198.     bra.s    Rled01        get next character
  1199.  
  1200. BtoB2    move.b    d0,0(a0,d2.w)    move character to output buffer
  1201.     addq    #1,d2        inc buffer pointer
  1202.     addq    #1,d1        inc buffer pointer
  1203.     bra    Rled01        get next character
  1204.     
  1205. BtoB3    move.b    d0,0(a0,d2.w)    move character to output buffer
  1206.     addq    #1,d2        inc buffer pointer
  1207.     bra    Rled01        get next character
  1208.  
  1209. Val0    move.b    #'0',0(a0,d2.w)    move "0" to output buffer
  1210.     addq    #1,d2        inc buffer pointer
  1211.     moveq    #3,d1        move " ? " to output buffer. (? = +,-,*,/,=)
  1212.     bra.s    BtoB1
  1213.  
  1214. ;******************************************************************
  1215. ;*           Copy from tempory buffer to output buffer            *
  1216. ;*           Inputs: a0 pointer to destination buffer             *
  1217. ;*                   a1 pointer to source                         *
  1218. ;******************************************************************
  1219.  
  1220. BTcopy    moveq    #0,d0
  1221.     moveq    #0,d2
  1222.     moveq    #0,d1
  1223.     addq    #1,d3        compensate for last subq of d3
  1224. BTcopy1    move.b    0(a1,d3.w),d0    get character from buffer
  1225.     addq    #1,d3        inc buffer pointer
  1226.     cmpi.b    #LF,d0        end of tempory buffer
  1227.     beq.s    BTcopy2        yes, end routine
  1228.     move.b    d0,0(a0,d2.w)    move character to output buffer
  1229.     addq    #1,d2        inc buffer pointer
  1230.     bra    BTcopy1        get next character
  1231.  
  1232. BTcopy2    move.b    d0,0(a0,d2.w)    move character to output buffer
  1233.     addq    #1,d2        inc buffer pointer
  1234.     move.b    #0,0(a0,d2.w)    put a NULL at end of output string
  1235.     rts
  1236.  
  1237.  
  1238. ;******************************************************************
  1239. ;*                                                                *
  1240. ;*                    Variables and Constants                     *
  1241. ;*                                                                *
  1242. ;******************************************************************
  1243.  
  1244. VarPtr    ds.l    1
  1245. Var1    ds.l    1
  1246. Var2    ds.l    1
  1247. Total    ds.l    2
  1248.  
  1249. func    dc.b    0    ; 0,1,2,3,4 none,add,sub,Mult,Div
  1250.  
  1251. neg    dc.b    0
  1252.  
  1253. err    dc.b    0
  1254.     
  1255. BuffT    ds.b    148
  1256. BuffTE    dc.b    $0a
  1257.  
  1258. BuffHS    dc.b    "HEX   "
  1259. BuffH    ds.b    52
  1260. BuffHe    dc.b    0
  1261. BuffOS    dc.b    "OCT   "
  1262. BuffO    ds.b    64
  1263. BuffOE    dc.b    0
  1264. BuffBS    dc.b    "BIN   "
  1265. BuffB    ds.b    148
  1266. BuffBE    dc.b    0
  1267. BuffDS    dc.b    "DEC   "
  1268. BuffD    ds.b    55
  1269. BuffDE    dc.b    0
  1270. rem    dc.b    " remainder"
  1271.  
  1272.  
  1273.     even
  1274.     
  1275. DecTemp    ds.w    6
  1276. DecCon0    dc.w    $0000,$0000,$0000,$0000,$0000,$0001
  1277. DecCon1    dc.w    $0000,$0000,$0000,$0000,$0000,$0016
  1278. DecCon2    dc.w    $0000,$0000,$0000,$0000,$0000,$0256
  1279. DecCon3    dc.w    $0000,$0000,$0000,$0000,$0000,$4096
  1280. DecCon4    dc.w    $0000,$0000,$0000,$0000,$0006,$5536
  1281. DecCon5    dc.w    $0000,$0000,$0000,$0000,$0104,$8576
  1282. DecCon6    dc.w    $0000,$0000,$0000,$0000,$1677,$7216
  1283. DecCon7    dc.w    $0000,$0000,$0000,$0002,$6843,$5456
  1284. DecCon8    dc.w    $0000,$0000,$0000,$0042,$9496,$7296
  1285. DecCon9    dc.w    $0000,$0000,$0000,$0687,$1947,$6736
  1286. DecConA    dc.w    $0000,$0000,$0001,$0995,$1162,$7776
  1287. DecConB    dc.w    $0000,$0000,$0017,$5921,$8604,$4416
  1288. DecConC    dc.w    $0000,$0000,$0281,$4749,$7671,$0656
  1289. DecConD    dc.w    $0000,$0000,$4503,$5996,$2737,$0496
  1290. DecConE    dc.w    $0000,$0007,$2057,$5940,$3792,$7936
  1291. DecConF    dc.w    $0000,$0115,$2921,$5046,$0694,$6976
  1292. DecEND    dc.w    $0000,$0000,$0000,$0000,$0000,$0000
  1293.  
  1294. DecSize    equ    (DecCon0-DecTemp)-1
  1295.  
  1296.     even
  1297. ipadd    dc.l    0
  1298. iplen    dc.w    0
  1299. stdout    dc.l    0
  1300. stdin    dc.l    0
  1301. DosBase    dc.l    0
  1302. DosName    dc.b    "dos.library",0
  1303.  
  1304. LF    equ    $0a
  1305.  
  1306. blank    dc.b    LF,0
  1307.  
  1308. HtoAI    dc.b    "You stuffed it up again",LF,0
  1309.  
  1310. oInfo    dc.b    "Error in operator",LF,0
  1311.  
  1312. hInfo    dc.b    "Error in hexadecimal number",LF,0
  1313.  
  1314. OInfo    dc.b    "Error in octal number",LF,0
  1315.  
  1316. BInfo    dc.b    "Error in binary number",LF,0
  1317.  
  1318. DInfo    dc.b    "Error in Decimal number",LF,0
  1319.  
  1320. adderrI    dc.b    "Overflow occured in addition, numbers are to large.",LF,0
  1321.  
  1322. suberrI    dc.b    "Overflow occured in subtraction, numbers are to large.",LF,0
  1323.  
  1324. dbyzI    dc.b    "Divid by zero",LF,0
  1325.  
  1326. Info    dc.b    "CAL <base> number operator <base> number <=> [return]",LF
  1327.     dc.b    " base: $ = HEX, @ = Octal, % = binary, none = decimal",LF
  1328.     dc.b    " number: HEX max 7FFFFFFF t0 80000000,",LF
  1329.     dc.b    "         Decimal max +/-2147483647",LF 
  1330.     dc.b    " operator: +,-,*,/",LF,LF,0
  1331.  
  1332.     end
  1333.  
  1334.